package controllers;

import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;

import Entity.User;

import messagesPacks.SimpleIntMessage;
import messagesPacks.UsersMSG;

/**
 * This class represents the OBL system administrator operations.
 * @author Alon Shahaf
 * @Date 01.01.2013
 */	
public class AdminUIP implements Observer 
{

	public AdminUIP()
	{
		System.out.println("AdminUIP Created.");
		WelcomeUIP.client.addObserver(this);
	}
	
	/**
	 * Returns the current list of locked users.
	 * @author Alon Shahaf
	 * @Date 01.01.2013
	 * @return List of locked users
	 */	
	public ArrayList<String> getLockedUsers()
	{
		ArrayList<String> lockedUsers = new ArrayList<String>();
		UsersMSG locked_msg = new UsersMSG(UsersMSG.op_type.ADMIN_listLocked);

		WelcomeUIP.client.setMaxRetries(2);
		WelcomeUIP.client.setWaitTime(3000);
		Object return_obj = null;
		return_obj = WelcomeUIP.client.sendToServerAndWait(locked_msg, locked_msg);
		
		if (return_obj==null)
		{
			// Timeout OR error in transmit.
			System.out.println("AdminUIP: (getLockedUsers) server returned null!");
		}
		else
		{
			System.out.println("AdminUIP: (getLockedUsers) total locked users = " + ((UsersMSG)return_obj).getUsers().size());
			// Convert the hashtable to arraylist to display in JList.
			lockedUsers.clear();
			for (User val : ((UsersMSG)return_obj).getUsers().values() ) 
			{
				lockedUsers.add(val.getID());
			}
		}		
		return lockedUsers;
	}
	
	/**
	 * Unlocks a specific user from the system.
	 * @author Alon Shahaf
	 * @Date 04.01.2013
	 * @param	User to unlock
	 * @return -99	Error, -1	User already unlocked,  1	User unlocked successfully
	 */	
	public int unlockUser(String user)
	{
		System.out.println("AdminUIP: (unlockUser) unlock user activated. user=" + user);
		if (!user.isEmpty())
		{		
			// Create a new message containing the user to unlock.
			UsersMSG unlock_msg = new UsersMSG(UsersMSG.op_type.ADMIN_unlock);
			unlock_msg.addUser(0, new User(user,"",1,1));
			
			System.out.println("user = " + unlock_msg.getUser(0).getID());
			
			WelcomeUIP.client.setMaxRetries(2);
			WelcomeUIP.client.setWaitTime(3000);
			Object return_obj = null;
			return_obj = WelcomeUIP.client.sendToServerAndWait(unlock_msg, new SimpleIntMessage(SimpleIntMessage.op_type.ADMIN_unlock,1));
			
			if (return_obj==null)
			{
				// Timeout OR error in transmit.
				System.out.println("AdminUIP: (unlockUser) unlock result=NULL");
			}
			else
			{
				System.out.println("AdminUIP: (unlockUser) unlock result = " + ((SimpleIntMessage)return_obj).getResult());
				if (((SimpleIntMessage)return_obj).getResult() == -99)
				{
					System.out.println("AdminUIP: (unlockUser) query error!");	
					return -99;
				}
				else if(((SimpleIntMessage)return_obj).getResult() == 1)
				{
					return 1;
				}
			}
		}
		return -1;
	}

	/**
	 * Creates a new librarian or librarian manager in the system.
	 * @author Alon Shahaf
	 * @Date 05.01.2013
	 * @param	id	- The user ID
	 * @param	fname - The user first name
	 * @param	lname - The user last name
	 * @param	email - The user email
	 * @param	manager	- True if the librarian is also a manager, false otherwise.
	 * @return -99	Error, -1	User already exists, 1	Librarian created
	 */	
	public int createLibrarian(String id, String fname, String lname, String email, boolean manager)
	{
		System.out.println("AdminUIP: (createLibrarian) ID=" + id + "FName=" + fname + "LName=" + lname + "Email=" + email + "Manager=" + manager);
		// Create a new message containing the librarian to create.
		UsersMSG newlib_msg = new UsersMSG(UsersMSG.op_type.ALL_createUser);
		int permission = 2;
		if (manager) 
			permission = 1;
		newlib_msg.addUser(0, new User(id,"12345",fname,lname,"",email,"",permission,0));
		
		WelcomeUIP.client.setMaxRetries(2);
		WelcomeUIP.client.setWaitTime(3000);
		Object return_obj = null;
		return_obj = WelcomeUIP.client.sendToServerAndWait(newlib_msg, new SimpleIntMessage(SimpleIntMessage.op_type.ADMIN_newlibrarian,1));
		
		if (return_obj==null)
		{
			// Timeout OR error in transmit.
			System.out.println("AdminUIP: (createLibrarian) result=NULL");
		}
		else
		{
			System.out.println("AdminUIP: (createLibrarian) result = " + ((SimpleIntMessage)return_obj).getResult());
			if (((SimpleIntMessage)return_obj).getResult() == 1)
			{
				System.out.println("AdminUIP: (createLibrarian) user created successfully!");	
				return 1;
			}
			else if(((SimpleIntMessage)return_obj).getResult() == -1)
			{
				System.out.println("AdminUIP: (createLibrarian) user already exists!");
				return -1;
			}
		}
		return -99;
	}
	
	@Override
	public void update(Observable arg0, Object arg1) 
	{
		// TODO Auto-generated method stub
		System.out.println("AdminUIP: Recieved notify: arg0:   " + arg0.toString() + "   |   arg1: "+ arg1.toString());
	}

	/**
	 * Simulation of graduation event received by external system to fire-up some operation meant to be executed in the OBL system.
	 * @author Alon Shahaf
	 * @Date 10.01.2013
	 * @param	id	- The user ID
	 * @return -99 - Error, -2 - the user doesn't exists
	 * 		  -1 - user cannot be graduated - he's not a subscriber but has a role in the OBL system.
	 * 		   0 - user is suspended due to borrowed books.
	 * 		   1 - user graduated OK - the user is locked successfully and was disconnected
	 * 	  	   2 - user graduated OK - the user is locked successfully and is not connected
	 */	
	public int graduateUser(String userID) 
	{
		System.out.println("AdminUIP: (graduateUser) ID=" + userID);
		// Create a new message containing the user to mark as graduated.
		UsersMSG grad_msg = new UsersMSG(UsersMSG.op_type.ADMIN_graduate);
		grad_msg.addUser(0, new User(userID,"","","","","","",0,0));			// Other fields are not necessary, only user ID.
		
		WelcomeUIP.client.setMaxRetries(2);
		WelcomeUIP.client.setWaitTime(3000);
		Object return_obj = null;
		return_obj = WelcomeUIP.client.sendToServerAndWait(grad_msg, new SimpleIntMessage(SimpleIntMessage.op_type.ADMIN_graduate,1));
		
		if (return_obj==null)
		{
			// Timeout OR error in transmit.
			System.out.println("AdminUIP: (graduateUser) result=NULL");
		}
		else
		{
			System.out.println("AdminUIP: (graduateUser) result = " + ((SimpleIntMessage)return_obj).getResult());
			if (((SimpleIntMessage)return_obj).getResult() == 2)
			{
				System.out.println("AdminUIP: (graduateUser) user graduated successfully!");	
				return 2;
			}			
			if (((SimpleIntMessage)return_obj).getResult() == 1)
			{
				System.out.println("AdminUIP: (graduateUser) user graduated successfully (forced to logout)!");	
				return 1;
			}
			else if(((SimpleIntMessage)return_obj).getResult() == 0)
			{
				System.out.println("AdminUIP: (graduateUser) user is now suspended - active borrow(s) exists! (forced to logout)");
				return 0;
			}
			else if(((SimpleIntMessage)return_obj).getResult() == -1)
			{
				System.out.println("AdminUIP: (graduateUser) user cannot graduate - not a subscriber!");
				return -1;				
			}
			else if(((SimpleIntMessage)return_obj).getResult() == -2)
			{
				System.out.println("AdminUIP: (graduateUser) no such user!");
				return -2;				
			}
			else if(((SimpleIntMessage)return_obj).getResult() == -3)
			{
				System.out.println("AdminUIP: (graduateUser) user is now suspended - active borrow(s) exists!");
				return -3;
			}			
		}
		return -99;
	}
}
